package componentloader

import (
	"zstackgo/spring"

	"github.com/go-spring/spring-core/gs"
	"github.com/meilihao/golib/v2/log"
	"go.uber.org/zap"
)

var (
	isInit bool
	ioc    gs.Container
)

type ComponentLoaderImpl struct {
	PluginRegistry PluginRegistryIN
}

func NewComponentLoaderImpl(appCtx gs.Container) ComponentLoader {
	impl := new(ComponentLoaderImpl)
	impl.CheckInit()
	ioc = appCtx

	return impl
}

func (impl *ComponentLoaderImpl) CheckInit() {
	if isInit {
		log.Glog.Fatal("Nested ComponentLoader initialization detected. DO NOT call Platform.getComponentLoader() in bean's constructor, it causes nested initialization")
	}

	isInit = true
}

func (impl *ComponentLoaderImpl) GetComponent(name string) interface{} {
	i := spring.GlobalMyContainer.GetValueByBeanName(name)
	if i == nil {
		log.Glog.Fatal("Cannot find bean with class", zap.String("name", name))
	}

	return i
}

func (impl *ComponentLoaderImpl) GetComponentNoExceptionWhenNotExisting(name string) interface{} {
	return spring.GlobalMyContainer.GetValueByBeanName(name)
}

func (impl *ComponentLoaderImpl) GetPluginRegistry() PluginRegistry {
	if impl.PluginRegistry == nil {
		impl.PluginRegistry = NewPluginRegistryImpl()
	}
	impl.PluginRegistry.Initialize()

	return impl.PluginRegistry
}

func (impl *ComponentLoaderImpl) GetComponentByBeanName(beanName string) interface{} {
	return spring.GlobalMyContainer.GetValueByBeanName(beanName)
}
